﻿using NetDh.RedisUtility;
using ServiceStack;
using ServiceStack.Redis;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace NetDh.TestConsole
{
    public class RedisHandleExample
    {
        public static RedisHandle RedisHandle { get; set; }
        public static RedisHandle RedisHandleDb1 { get; set; }
        static RedisHandleExample()
        {
            RedisHandle = new RedisHandle();
            //RedisHandleDb1和RedisHandle是连接同一个Redis服务端，只是指向的db不一样，因此建议可以共用连接池对象
            //RedisHandleDb1 = new RedisHandle(RedisHandle.PooledClientManager,1);//第二个参数1是Db=1。
        }

        public static void TestMain()
        {
            #region //测试从连接池中取出的对象的db是否受之前ChangeDb影响，结果->是受影响
            ////这边设置了连接池最大连接数是1
            //var handle1= RedisHandle.PooledClientManager.GetClient() as RedisClient;
            //handle1.ChangeDb(1);
            //var value1 = handle1.GetValue("test2");
            //handle1.Dispose();
            ////第二次取出来的对象handle2和handle1是同一个对象，因此已经是指向ChangeDb(1)。
            //var handle2 = RedisHandle.PooledClientManager.GetClient() as RedisClient;
            //var value2 = handle1.GetValue("test2");
            //handle2.Dispose();
            #endregion

            //不经过连接池直接获取连接实例
            //RedisClient client = new RedisClient("localhost", 6379, "password"); 

            #region //以下代码可以破解6000的限制，不过每次系统启动时都要调用一次。
            //var licenseKey = new LicenseKey()
            //{
            //    Ref = "pedoc",
            //    Expiry = DateTime.Now.AddDays(365 * 1000),
            //    Hash = string.Empty,
            //    Name = "pedoc",
            //    Type = LicenseType.Enterprise
            //};
            //var field = typeof(LicenseUtils).GetField("__activatedLicense",
            //BindingFlags.Static | BindingFlags.NonPublic);
            //var keyType = field.FieldType;
            //var constructorInfos = keyType.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
            //var constructorInfo = constructorInfos[0];
            //var key = constructorInfo.Invoke(new object[] { licenseKey });
            //field.SetValue(null, key);
            //var licenceAll = LicenseUtils.HasLicensedFeature(LicenseFeature.All);
            ////Debug.Assert(licenceAll);
            #endregion

            #region //用十六进制编辑器修改ServiceStack.Text.dll的限制次数，可破解6000限制。
            //for (int i = 0; i < 8002; i++)
            //{
            //    var value = ReHandle.GetValue("test1");                
            //}
            #endregion

            #region 测试Hash存储，一次写入Hash多个值操作，原理是内部使用了redis的HMSET命令
            var user = new TestUser()
            {
                Id = 1,
                Name = "aa",
                CreateTime = DateTime.Now
            };
            //ReHandle.StoreAsHash(user);
            //Store(user)产生的数据是key-value类型：key为urn:testuser:1，value为"{\"Id\":1,\"Name\":\"aa\",\"CreateTime\":\"\\/Date(1570543580256+0800)\\/\"}"
            RedisHandle.Store(user);
            user = new TestUser()
            {
                Id = 2,
                Name = "bb",
                CreateTime = DateTime.Now
            };
            //StoreAsHash(user)产生的数据是hash类型，key为urn:testuser:2，第一行field是Id，value是2，第二行field是Name，value是"bb"..
            RedisHandle.StoreAsHash(user);
            var dict = new Dictionary<string, string>()
            {
                {"d1","1"},{"d2","2"},{"d3","3"}
            };
            //SetRangeInHash("mydict1", dict);产生的数据是hash类型，key为mydict1，第一行field是d1,value是1，第二行field是d2，value是2..
            RedisHandle.SetRangeInHash("mydict1", dict);
            //StoreAsHash和SetRangeInHash实现一次多个值写入，原理其实就是用redis的HMSET命令(Hash-Multi-Set)。
            #endregion

            Console.WriteLine("ok");
        }
    }

    public class TestUser
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime CreateTime { get; set; }
    }
}
